use crate::utils::service_config::ServiceConfig;
use reqwest::Response;
use serde_json::Value;
use std::fmt::Debug;
use std::future::Future;
use std::time::Duration;
use tokio::runtime::Runtime;

pub fn handle_http<S, F, T>(
    service_name: String,
    url_name: String,
    body: Value,
    success: S,
    failed: F,
) -> Result<(), String>
where
    S: FnOnce(Response) -> T + Send + 'static,
    F: FnOnce(Response) + Send + 'static,
    T: Future<Output = ()> + Send + 'static,
{
    let rt = Runtime::new().expect("创建tokio运行时失败");
    let service_config = ServiceConfig::new();
    let mut url: String;
    let mut method: String;
    match service_name.as_str() {
        "maview" => {
            url = service_config.get_maview_url(&url_name);
            method = service_config.get_maview_method(&url_name);
        }
        "center" => {
            url = service_config.get_center_url(&url_name);
            method = service_config.get_center_method(&url_name);
        }
        _ => {
            return Err("未知的服务".to_string());
        }
    };
    rt.block_on(http_request(vec![url, method], body, success, failed))
}

async fn http_request<S, F, T>(
    url_config: Vec<String>,
    body: Value,
    success: S,
    failed: F,
) -> Result<(), String>
where
    S: FnOnce(Response) -> T + Send + 'static,
    F: FnOnce(Response) + Send + 'static,
    T: Future<Output = ()> + Send + 'static,
{
    let url = url_config[0].clone();
    let method = url_config[1].clone();
    let client = reqwest::Client::new();
    match method.as_str() {
        "GET" => {
            let response = client
                .get(url)
                .timeout(Duration::from_secs(5))
                .send()
                .await
                .unwrap();
            if response.status().is_success() {
                success(response).await;
            } else {
                failed(response);
            }
            Ok(())
        }
        "POST" => {
            let response = client
                .post(url)
                .timeout(Duration::from_secs(5))
                .json(&body)
                .send()
                .await
                .unwrap();
            if response.status().is_success() {
                success(response).await;
            } else {
                failed(response);
            }
            Ok(())
        }
        "PUT" => {
            let response = client
                .put(url)
                .timeout(Duration::from_secs(5))
                .json(&body)
                .send()
                .await
                .unwrap();
            if response.status().is_success() {
                success(response).await;
            } else {
                failed(response);
            }
            Ok(())
        }
        "DELETE" => {
            let response = client
                .delete(url)
                .timeout(Duration::from_secs(5))
                .json(&body)
                .send()
                .await
                .unwrap();
            if response.status().is_success() {
                success(response).await;
            } else {
                failed(response)
            }
            Ok(())
        }
        _ => Err("未知的请求方法".to_string()),
    }
}
